package com.googlecode.xpathproxy;

import com.googlecode.xpathproxy.conversion.Converter;
import org.apache.log4j.Logger;
import org.w3c.dom.Node;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;


public class XPathProxyFactory<T> {

    private static final Logger log = Logger.getLogger(XPathProxyFactory.class);

    private final Class<T> targetInterface;
    private List<Converter> converters = new ArrayList<Converter>();

    public XPathProxyFactory(Class<T> targetInterface) {
        assert targetInterface.isInterface() : "targetInterface constructor argument must be an interface";
        this.targetInterface = targetInterface;

    }

    public void registerConverter(Converter converter) {
        converters.add(converter);
    }

    public Converter[] getConverters() {
        return converters.toArray(new Converter[converters.size()]);
    }

    public Class<T> getTargetInterface() {
        return targetInterface;
    }

    @SuppressWarnings("unchecked")
    public T createProxy(Node element) throws IllegalArgumentException {
        log.debug("Creating proxy for [" + targetInterface + "]");

        return (T) Proxy.newProxyInstance(
                targetInterface.getClassLoader(),
                new Class[]{targetInterface},
                newInvocationHandler(element));
    }

    protected XPathMethodInvocationHandler newInvocationHandler(Node element) {
        return new XPathMethodInvocationHandler(getTargetInterface(), element, getConverters());
    }

}
